package com.dhj.yygh.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dhj.yygh.client.HospitalClient;
import com.dhj.yygh.common.exception.YyghException;
import com.dhj.yygh.common.helper.HttpRequestHelper;
import com.dhj.yygh.common.result.ResultCodeEnum;
import com.dhj.yygh.enums.OrderStatusEnum;
import com.dhj.yygh.enums.PaymentStatusEnum;
import com.dhj.yygh.enums.PaymentTypeEnum;
import com.dhj.yygh.mapper.PayInfoMapper;
import com.dhj.yygh.model.order.OrderInfo;
import com.dhj.yygh.model.order.PaymentInfo;
import com.dhj.yygh.service.OrderInfoService;
import com.dhj.yygh.service.PayInfoService;
import com.dhj.yygh.vo.order.SignInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service
public class PayInfoServiceImpl extends ServiceImpl<PayInfoMapper, PaymentInfo> implements PayInfoService {

    @Autowired
    OrderInfoService orderInfoService;

    @Autowired
    HospitalClient hospitalClient;

    /**
     * 保存微信支付的信息
     *
     * @param orderInfo 订单 id
     * @param status    支付的类型(微信/支付宝)
     */
    @Override
    public void savePaymentInfo(OrderInfo orderInfo, Integer status) {

        // 根据 orderId 和支付类型查询是否存在支付记录
        QueryWrapper<PaymentInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("order_id", orderInfo.getId());
        wrapper.eq("payment_type", status);

        // 查询是否有记录
        Integer count = baseMapper.selectCount(wrapper);

        if (count == 0) {
            // 保存交易记录
            PaymentInfo paymentInfo = new PaymentInfo();
            paymentInfo.setCreateTime(new Date());// 支付时间
            paymentInfo.setOrderId(orderInfo.getId());// 订单 id
            paymentInfo.setPaymentType(status);// 支付类型
            paymentInfo.setOutTradeNo(orderInfo.getOutTradeNo());// 订单编号
            paymentInfo.setPaymentStatus(PaymentStatusEnum.UNPAID.getStatus());
            String subject = new DateTime(orderInfo.getReserveDate())
                    .toString("yyyy-MM-dd") + "|" + orderInfo.getHosname() + "|"
                    + orderInfo.getDepname() + "|" + orderInfo.getTitle();// 设置交易的内容
            paymentInfo.setSubject(subject);
            paymentInfo.setTotalAmount(orderInfo.getAmount());// 支付金额

            baseMapper.insert(paymentInfo);
        }
    }

    /**
     * 根据订单 id 更新订单的支付状态
     *
     * @param orderId   订单 id
     * @param resultMap 支付参数的 Map 集合
     */
    @Override
    public void paySuccess(Long orderId, Map<String, String> resultMap) {

        // 更新支付记录的支付信息
        QueryWrapper<PaymentInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("order_id", orderId);
        wrapper.eq("payment_type", PaymentTypeEnum.WEIXIN.getStatus());
        PaymentInfo paymentInfo = baseMapper.selectOne(wrapper);

        if (null == paymentInfo) {
            throw new YyghException(ResultCodeEnum.PARAM_ERROR);
        }
        paymentInfo.setTradeNo(resultMap.get("transaction_id"));// 微信返回的订单号
        paymentInfo.setPaymentStatus(PaymentStatusEnum.PAID.getStatus());// 支付状态
        paymentInfo.setCallbackTime(new Date());// 订单的支付时间
        paymentInfo.setCallbackContent(resultMap.toString());// 将整个支付返回的 Map 集合存入数据库中，方便后续查看

        baseMapper.updateById(paymentInfo);

        // 更新订单的支付状态信息
        OrderInfo orderInfo = orderInfoService.getById(orderId);
        orderInfo.setOrderStatus(OrderStatusEnum.PAID.getStatus());
        orderInfoService.updateById(orderInfo);

        // 调用医院接口，更新医院订单的支付信息 /order/updatePayStatus
        SignInfoVo signInfoVo = hospitalClient.getSignInfoVo(orderInfo.getHoscode());// 获取医院签名信息

        // 向医院发送请求
        Map<String, Object> hospParamMap = new HashMap<>();// 封装医院请求的参数
        hospParamMap.put("number", orderInfo.getNumber());
        hospParamMap.put("signKey", signInfoVo.getSignKey());
        JSONObject result = HttpRequestHelper.sendRequest(hospParamMap, signInfoVo.getApiUrl() + "/order/updatePayStatus");

        log.info(result.getInteger("code") == 200 ? "平台与医院双方的支付信息更新成功!" : "平台与医院双方的支付信息更新失败!");
    }

    /**
     * 获取支付记录
     *
     * @param orderId
     * @param paymentType
     * @return
     */
    @Override
    public PaymentInfo getPaymentInfo(Long orderId, Integer paymentType) {
        QueryWrapper<PaymentInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("order_id", orderId);
        wrapper.eq("payment_type", paymentType);

        PaymentInfo paymentInfo = baseMapper.selectOne(wrapper);
        return paymentInfo;
    }
}
